﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace B121B {
    /// <summary>
    /// The different kinds of heating systems an autocamper can have
    /// </summary>
    public enum AutoCamperHeatingSystem { Gas, Electricity, Oil };

    /// <summary>
    /// Autocamper class
    /// </summary>
    public class Autocamper : Vehicle, IHasSeatsAndSleepSeats {
        /// <summary>
        /// Autocamper constructor
        /// </summary>
        /// <param name="brand">Brand</param>
        /// <param name="model">Model</param>
        /// <param name="km">Distance driven</param>
        /// <param name="year">Production year</param>
        /// <param name="price">Price</param>
        /// <param name="motorSize">Size of motor</param>
        /// <param name="km_l">Travel distance on 1 liter of fuel</param>
        /// <param name="fueltype">Fueltype</param>
        /// <param name="seats">Number of seats</param>
        /// <param name="sleepSeats">Number of sleeping seats</param>
        /// <param name="heatingSystem">Heating system</param>
        public Autocamper(string brand, string model, int km, DateTime year, double price, double motorSize, double km_l, Fuel fueltype, int seats, int sleepSeats, AutoCamperHeatingSystem heatingSystem)
            : base(brand, model, km, year, price, motorSize, km_l, fueltype) {
            Seats = seats;
            SleepSeats = sleepSeats;
            HeatingSystem = heatingSystem;
            VehicleType = VehicleTypes.AutoCamper;
        }

        #region Properties
        /// <summary>
        /// Max speed
        /// </summary>
        public override int MaxSpeed { get { return 180; } }

        /// <summary>
        /// Motor size
        /// </summary>
        public override double MotorSize {
            get { return _MotorSize; }
            set {
                if (!IsMotorSizeOkay(2.4, 6.2, value)) { // Check for valid size
                    throw new ArgumentOutOfRangeException();
                } else {
                    _MotorSize = value;
                }
            }
        }
        private double _MotorSize;

        /// <summary>
        /// Autocamper calculate energy class a little diferent
        /// </summary>
        public override char EnergyClass {
            get {
                double multiplier = 0;
                switch (HeatingSystem) {
                    case AutoCamperHeatingSystem.Oil:
                        multiplier = 0.7;
                        break;
                    case AutoCamperHeatingSystem.Electricity:
                        multiplier = 0.8;
                        break;
                    case AutoCamperHeatingSystem.Gas:
                        multiplier = 0.9;
                        break;
                    default:
                        multiplier = 0;
                        break;
                }
                return CalcEnergyClass(FuelType, KM_L * Math.Pow(multiplier, -1)); // Wuhu, math!
            }
        }

        /// <summary>
        /// Number of seats
        /// </summary>
        public int Seats {
            get { return _Seats; }
            set {
                if (value < 0) { // Check for valid amount of seats
                    throw new ArgumentOutOfRangeException("An autocamper cannot have a negative amount of seats");
                } else {
                    _Seats = value;
                }
            }
        }
        private int _Seats;

        /// <summary>
        /// Number of sleep seats
        /// </summary>
        public int SleepSeats {
            get { return _SleepSeats; }
            set {
                if (value < 0) { // Check for valid amount of sleeping seats
                    throw new ArgumentOutOfRangeException("An autocamper cannot have a negative amount of sleeping seats");
                } else {
                    _SleepSeats = value;
                }
            }
        }
        private int _SleepSeats;

        /// <summary>
        /// The heating system
        /// </summary>
        public AutoCamperHeatingSystem HeatingSystem { get; set; }
        #endregion

        #region Override Equals
        public override bool Equals(object obj) {
            if (obj == null) { return false; } // Check for null

            // We don't check for reference equality

            if (this.GetType() != obj.GetType()) { return false; } // Same type?

            return Equals((Vehicle)obj); // More specific check
        }
        public bool Equals(Autocamper obj) {
            if (obj == null) { return false; }

            return // Check all values
                base.Equals(obj) &&
                this.Seats == obj.Seats &&
                this.SleepSeats == obj.Seats &&
                this.HeatingSystem == obj.HeatingSystem;
        }
        public override int GetHashCode() {
            return base.GetHashCode(); // We do not check has code, as we check on values only
        }

        public static bool operator ==(Autocamper obj1, Autocamper obj2) {
            if (ReferenceEquals(obj1, null)) {
                return ReferenceEquals(obj2, null); // Both null, equal, otherwise not
            }
            return obj1.Equals(obj2);
        }
        public static bool operator !=(Autocamper obj1, Autocamper obj2) {
            return !(obj1 == obj2);
        }
        #endregion

        /// <summary>
        /// Shows the autocamper information, formatted for console output
        /// </summary>
        /// <returns>Autocamper information as a string</returns>
        public override string ToString() {
            return base.ToString() +
                "  Seats: " + Seats + Environment.NewLine +
                "  SleepSeats: " + SleepSeats + Environment.NewLine +
                "  Heating System: " + HeatingSystem;
        }
    }
}